package com.violet.myorm;

import com.violet.myorm.core.condition.LambdaWhere;
import com.violet.myorm.core.execute.Delete;
import com.violet.myorm.core.execute.Insert;
import com.violet.myorm.core.execute.Query;
import com.violet.myorm.core.execute.Update;
import com.violet.myorm.core.source.Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public abstract class Model {
    public static <E extends Model> Query<E> query(Class<E> clazz) {
        return new Query<>(clazz);
    }

    public static <E extends Model> Delete<E> delete(Class<E> clazz) {
        return new Delete<>(clazz);
    }

    public static <E extends Model> Update<E> update(Class<E> clazz) {
        return new Update<>(clazz);
    }

    public static <E extends Model>Insert<E> create(Class<E> clazz) {
        return new Insert<>(clazz);
    }

    public int delete() {
        try {
            Field key = Reflect.getPrimaryKey(this.getClass());
            String name = Reflect.getFieldName(key);
            return delete(this.getClass())
                    .where(new LambdaWhere().eq(name, key.get(this)))
                    .executeDelete();
        }
        catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public int update() {
        try {
            Field key = Reflect.getPrimaryKey(this.getClass());
            String name = Reflect.getFieldName(key);
            Update update = update(this.getClass()).where(new LambdaWhere().eq(name, key.get(this)));
            for (Field field : Reflect.getNormFields(this.getClass())) {
                if (field.equals(key)) continue;
                update.set(Reflect.getFieldName(field), field.get(this));
            }
            return update.executeUpdate();
        }
        catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public int insert() {
       return create(this.getClass()).insert(this).executeCreate();
    }

}
